﻿using Bridge.System.Domain;
using Bridge.Shared.Enums.IdentityService;
using Bridge.Shared.Models;
using Mapster;
using Menus.Output;
using Microsoft.AspNetCore.Hosting;
using Microsoft.AspNetCore.Identity;
using Microsoft.AspNetCore.Mvc;
using Microsoft.EntityFrameworkCore;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Users;
using Users.Input;
using Users.Output;
using Volo.Abp;
using Volo.Abp.Application.Services;
using Volo.Abp.Data;
using Volo.Abp.Domain.Repositories;
using Volo.Abp.Identity;
using Volo.Abp.Threading;
using IdentityRole = Volo.Abp.Identity.IdentityRole;
using IdentityUser = Volo.Abp.Identity.IdentityUser;

namespace Bridge.System.Application
{

    public class UserService : ApplicationService, IUserService
    {
        protected IdentityUserManager _userManager { get; }
        private readonly IRepository<IdentityUser> _userRepository;
        private readonly IRepository<IdentityRole> _roleRepository;
        public UserService(IdentityUserManager userManager, IRepository<IdentityUser> _userRepository, IRepository<IdentityRole> roleRepository) { 
            this._userManager = userManager;
           this._userRepository = _userRepository;
            this._roleRepository = roleRepository;
        }
      public async  Task<ResponseResult<CreateUserOutput>> CreateUser(CreateUserInput input)
        {
            if (input == null)
            {
                return ResponseResult<CreateUserOutput>.Fail("参数不能为空！");
            }
            if (await _userRepository.AnyAsync(s => s.UserName == input.UserName))
            {
                return ResponseResult<CreateUserOutput>.Fail("用户名已存！");
            }
            var user = new IdentityUser(
                GuidGenerator.Create(),
                input.UserName,
                input.Email,
                CurrentTenant.Id
            )
            {
                Name = input.Name,
                CreatorId = CurrentUser.Id,
                CreationTime = DateTime.Now
            };
            _userManager.UserValidators.Clear();
            _userManager.PasswordValidators.Clear();
            input.Password = "Bridge0";
            input.RoleNames =new string[]{ "admin"};
            (await _userManager.CreateAsync(user, input.Password)).CheckErrors();
            (await _userManager.SetRolesAsync(user, input.RoleNames)).CheckErrors();
            await CurrentUnitOfWork.SaveChangesAsync();

            return ResponseResult<CreateUserOutput>.Success("操作成功！",null);
        }

        public async Task<ResponseResult> DeleteAsync(IdsInput<Guid> input)
        {
            if (CurrentUser == null)
            {
                return ResponseResult.Fail("用户未登录！");
            }
            List<IdentityUser> users = new List<Volo.Abp.Identity.IdentityUser>();
            foreach (var item in input.Ids)
            {
                var user = await _userManager.FindByIdAsync(item.ToString());
                if (user == null)
                {
                    return ResponseResult.Fail("用户不存在！");
                }

                users.Add(user);
            }
            
           foreach (var user in users)
            {
                await _userManager.DeleteAsync(user);

            }

           
            return ResponseResult.Success("操作成功！");
        }

      

        public async Task<ResponseResult> UpdateAsync(UpdateUserInput input)
        {
            _userManager.UserValidators.Clear();
            _userManager.PasswordValidators.Clear();

            var user =await _userManager.GetByIdAsync(input.Id);
        
            if (user == null)
            {
                return ResponseResult.Fail("用户不存在！");
            }
           await UpdateUserByInput(user,input);
            return ResponseResult.Success("操作成功！");
        }

        protected virtual async Task UpdateUserByInput(IdentityUser user, UpdateUserInput input)
        {

            if (!string.Equals(user.PhoneNumber, input.PhoneNumber, StringComparison.InvariantCultureIgnoreCase))
            {
                //验证修改后手机号是否重复
         
                if (!string.IsNullOrEmpty(input.PhoneNumber))
                {
                    if (await _userRepository.AnyAsync(p => p.Id != user.Id && p.PhoneNumber == input.PhoneNumber))
                    {
                        throw new Exception("手机号重复");
                    }
                }

                (await _userManager.SetPhoneNumberAsync(user, input.PhoneNumber)).CheckErrors();
            }

            if (!string.Equals(user.Email, input.Email, StringComparison.InvariantCultureIgnoreCase))
            {
                (await _userManager.SetEmailAsync(user, input.Email)).CheckErrors();
            }

            //(await _userManager.SetLockoutEnabledAsync(user, input.LockoutEnabled)).CheckErrors();

            user.Name = input.Name;
            user.LastModificationTime = DateTime.Now;
            user.LastModifierId = CurrentUser.Id;
            (await _userManager.UpdateAsync(user)).CheckErrors();

            if (input.RoleNames != null)
            {
                (await _userManager.SetRolesAsync(user, input.RoleNames)).CheckErrors();
            }
        }

        public async Task AddRoleForUser(AddRoleForUserInput input)
        {
            var user = await _userManager.GetByIdAsync(input.UserId);
            if(user == null)
            {
                throw new Exception("用户信息不存在！");
            }

            var rolseList = (await _roleRepository.GetQueryableAsync() ).Where(a=>input.Roles.Contains(a.Id));
            if(rolseList.Any()) {
                throw new Exception("角色信息不存在！");
            }

            var rolseNames = rolseList.Select(a => a.Name).ToList();

            await _userManager.SetRolesAsync(user,rolseNames);

            await _userRepository.UpdateAsync(user);

        }
  
        public async Task<ResponseResult<UserInfoOutput>> GetInfo()
        {
            var userInfo = new UserInfoOutput();

            var user = await _userManager.GetByIdAsync(CurrentUser.Id.Value);
            if(userInfo == null)
            {
                return ResponseResult<UserInfoOutput>.Fail("无用户记录！");
            }
            var roles =await  _userManager.GetRolesAsync(user);
            if(!roles.Any())
            {
                return ResponseResult<UserInfoOutput>.Fail("未分配角色！");
            }
            userInfo.Id = user.Id;
            userInfo.UserName = user.UserName;
            userInfo.Roles  = roles.ToList();
            //默认给所有权限
            userInfo.Permissions = new List<string>() { "*:*:*" };
            return ResponseResult<UserInfoOutput>.Success("ok",userInfo);

           

        }

        public async Task<ResponseResult<UserInfoOutput>> GetUserById(Guid Id)
        {
         var user = await   _userRepository.FirstOrDefaultAsync(x => x.Id == Id);
          if(user == null)
            {
                return ResponseResult<UserInfoOutput>.Fail("记录不存在！");
            }
            var dto = user.Adapt<UserInfoOutput>();
            return ResponseResult<UserInfoOutput>.Success("ok",dto);
        }

        public async Task<PageResponseResult<UserInfoOutput>> GetPageListAsync(GetUserPageListInput input)
        {
            var query = (await _userRepository.GetQueryableAsync()).WhereIf(!string.IsNullOrEmpty(input.UserName), a => a.Name.Contains(input.UserName)).Where(a=>a.UserName!="admin");

            var totalCount = query.Count();

            if (totalCount == 0)
            {
                return PageResponseResult<UserInfoOutput>.Fail("暂无记录");
            }
            var list = await query.Skip(input.PageIndex * input.PageSize).Take(input.PageSize).ToListAsync();

            var dto = list.Adapt<List<UserInfoOutput>>();

            return PageResponseResult<UserInfoOutput>.Success("ok", dto, input.PageSize, input.PageIndex, totalCount);
        }

        public async Task<ImportUserOutput> ImportUserAsync(List<ImportUserInput> input)
        {
            var errorMsg = new List<string>();
            int lineCount = 0;
            var dto = new ImportUserOutput();
            string password = "bridge0";
            try
            {
                var userExpandList = new List<UserExpand>();
                foreach (var item in input)
                {
                    lineCount++;
                    item.Email = string.IsNullOrEmpty(item.Email) ? $"{item.UserName}@wms.com" : item.Email;
                    var user = new IdentityUser(
                        GuidGenerator.Create(),
                        item.UserName,
                        item.Email,
                        CurrentTenant.Id
                    )
                    {
                        Name =  item.UserName,
                        CreatorId = CurrentUser.Id,
                        CreationTime = DateTime.Now
                    };

                    user.SetPhoneNumber(item.Phone, false);

                    _userManager.UserValidators.Clear();
                    _userManager.PasswordValidators.Clear();

                
                    //写入用类型和所属系统到扩展字段供token使用
           
                    try
                    {
                        (await _userManager.CreateAsync(user, password)).CheckErrors();

                        (await _userManager.SetRolesAsync(user, new string[] { item.RoleName })).CheckErrors();

                        (await _userManager.SetLockoutEnabledAsync(user, false)).CheckErrors();

                        dto.SuccessCount++;
                    }
                    catch (Exception ex)
                    {
                        dto.FailCount++;
                        await CurrentUnitOfWork.RollbackAsync();
                        errorMsg.Add($"第{lineCount}笔数据创建用户失败，原因{ex.Message}");
                        break;
                    }
                }
                await CurrentUnitOfWork.SaveChangesAsync();
            }
            catch (Exception ex)
            {
                dto.FailCount++;
                await CurrentUnitOfWork.RollbackAsync();
                errorMsg.Add($"第{lineCount}笔数据创建用户失败，原因{ex.Message}");
            }

            dto.ErrorMsg = string.Join("|", errorMsg);
            return dto;
        }

        public async Task<ResponseResult> ChangeIsActive(ChangeUseStatusInput input)
        {
            var user =await _userManager.GetByIdAsync(input.Id);
            if (user == null)
            {
                return ResponseResult.Fail("记录不存在！");
            }
            user.SetIsActive(input.IsActive);
            return ResponseResult.Success("操作成功！");
        }
        [RemoteService(IsMetadataEnabled = true)]
        [HttpGet]
        public async Task<List<IdentityUserDto>> GetUserListByRoleName(Guid roleId)
        {
            List<IdentityUserDto> users = new();

            var role = await (await _roleRepository.GetQueryableAsync()).FirstOrDefaultAsync(a => a.Id == roleId);
            if (role != null)
            {
           
            var identityUserList = await _userManager.GetUsersInRoleAsync(role.Name);

            users = identityUserList.Adapt<List<IdentityUserDto>>();

            }

           return users;
        }
        [RemoteService(IsMetadataEnabled = true)]
        [HttpGet]
        public async Task<IdentityUserDto> WfGetAsyncById(Guid id)
        {
            var user = await _userManager.GetByIdAsync(id);

            var result = user.Adapt<IdentityUserDto>();
            return result;
        }
    }
}
